package unamur.iodass.communication;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;

import org.apache.log4j.Logger;

import unamur.iodass.communication.messages.Deliver;
import unamur.iodass.communication.messages.Message;
import unamur.iodass.delivery.DeliveryHandler;






public class Server {

	private static final Logger logger = Logger.getLogger(Server.class);
	
	private volatile boolean started;
	
	Server() {
		// Nothing
	}

	/**
	 * Start the listener.
	 */
	void start() {
		started = true;
		Thread daemon = new Thread(new Daemon());
		daemon.start();
	}

	/**
	 * Stop the listener
	 */
	void stop() {
		started = false;
	}
	
	// Represent the daemon lunched when this is started
	private class Daemon implements Runnable {

		@Override
		public void run() {
			try {
				ServerSocket serverSocket = new ServerSocket(9001);
				while (started) {
					try {
						Socket socket = serverSocket.accept();
						new Thread(new Slave(socket)).start();
					} catch (SocketTimeoutException e) {
						// do nothing
					} catch (IOException e) {
						logger.error(e);
					}
				}
				serverSocket.close();
			} catch (IOException e) {
				logger.error(e);
			}
			logger.info("daemon stopped");
		}
		
	}
	
	// Represent a slave lunched by the daemon
	private class Slave implements Runnable {
		
		private Socket socket;
		
		private Slave(Socket socket) {
			this.socket = socket;
		}

		@Override
		public void run() {
			try {
				try {
					ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
					Message message = (Message) ois.readObject();
					
					if (message instanceof Deliver) {
						Deliver deliver = (Deliver) message;
						
						
						DeliveryHandler.getInstance().saveDelivery(deliver);
						
						DeliveryHandler.getInstance().showOnTerminal();
						logger.info("Delivery Handling");
					}
						

				} catch (ClassNotFoundException e) {
					logger.error(e);
				} catch (ClassCastException e) {
					logger.error(e);
				}
				socket.close();
			} catch (IOException e) {
				logger.error(e);
			}
		}
		
	}

}

